import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import routefinder.City;
import routefinder.IRoutesMap;
import routefinder.exception.RouteFinderException;
import routefinder.RouteFinderExtendedImpl;
import routefinder.RoutesMapCities;
import routefinder.loader.DefaultDataLoader;
import routefinder.loader.IDataLoader;
import routefinder.renderer.IRenderer;
import routefinder.renderer.RendererFactory;

/**
 *
 * @author Lucas
 */
public class Main {

    private static final Logger LOG = Logger.getLogger(Main.class.getName());

    /**
     * @param args 
     * param0: name of the origin city
     * param1: name of the destination city
     * param2: path to a file containing the graph map
     */
    public static void main(String[] args) throws IOException  {
        LogManager.getLogManager().readConfiguration(Thread.currentThread().getContextClassLoader().getResourceAsStream("logger.properties"));
        City origin = null;
        City destination = null;
        if (args.length < 2) {
            throw new RouteFinderException("Usage: java -jar jarName.jar originCityName destinationCityName [graphFile]");
        } else {
            origin = new City(args[0]);
            destination = new City(args[1]);
        }
        String graphDataFilePath = null;
        if (args.length == 3) {
            graphDataFilePath = args[2];
        }

        final IRoutesMap map = new RoutesMapCities();
        loadIntoMemory(graphDataFilePath, map);
        
        RouteFinderExtendedImpl facade = RouteFinderExtendedImpl.getInstance();
        facade.setRoutesMap(map);

        LOG.info("Executing algorithm...");

        final int shortestLength = facade.getShortestRouteLength(origin, destination);
        final Map<City, Integer> routes = facade.getAllShortestRouteLengths(origin);
        final int numberOfTrips = facade.getTrips(new City("C"), new City("C"), 3);
        final int tripsWithStrictNumberOfStops = facade.getTripsStrictStops(new City("A"), new City("C"), 4);

        HashMap<String, Object> params = new HashMap<String,Object>();
        params.put("shortestLength", shortestLength);
        params.put("routes", routes);
        params.put("origin", origin);
        params.put("destination", destination);
        params.put("numberOfTrips", numberOfTrips);
        params.put("tripsWithStrictNumberofStops", tripsWithStrictNumberOfStops);

        IRenderer renderer = RendererFactory.newInstance();
        renderer.render(params, System.out);
    }

    private static void loadIntoMemory(final String filePath, final IRoutesMap map) {
        InputStream is = null;
        if (filePath != null) {
            try {
                is = new FileInputStream(filePath);
            } catch (FileNotFoundException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.WARNING, "couldn't load file. trying the sample graph.", ex);
            }
        }
        if (is == null) {
            // couldn't load from specified file, try the default graph data file
            is = Thread.currentThread().getContextClassLoader().getResourceAsStream("exampleGraph.data");
        }

        IDataLoader dataLoader = new DefaultDataLoader();
        dataLoader.loadIntoMemory(is, map);
    }
}
